This section is intended to introduce the reader to various aspects of art, which may be related to various aspects of the present invention that are described and/or claimed below. This discussion is believed to be helpful in providing the reader with background information to facilitate a better understanding of the various aspects of the present invention. Accordingly, it should be understood that these statements are to be read in this light, and not as admissions of prior art.
It is relatively common for software providers to protect the integrity of a computer program with the goal of making sure that the program performs as intended. However, hackers commonly try to hack the program to perform in different ways. An example is that hackers sometimes wish to modify the code to get around access control features of the program in order to be able to use it without the necessary access rights.
Such reverse engineering of protected software is, for several reasons, an iterative process. First, an application is usually too big to be fully executed step by step. Second, when a protection mechanism detects a reverse activity, the hacker must restart the execution of the application to continue the analysis. An efficient means of preventing a hacker from learning from one execution to the next is address space randomization, as it thwarts the use of a breakpoint on a function previously pinpointed at a known address.
At present, address space randomization is mainly used in contexts like Address space layout randomization (ASLR) in stacks to prevent buffer overflow attacks. For example, ASLR makes the location of a section unpredictable in order to be resistant to replay attacks. Going one step further, some applications dynamically replace a portion of code at a random address. Bhatkar et al. (see Sandeep Bhatkar, Daniel C. DuVarney, and R. Sekar. Address Obfuscation: An Efficient Approach to Combat a Broad Range of Memory Error Exploits. In Proceedings of the USENIX Security Symposium. USENIX, 2003) present a different method to use address space randomization for code protection. However, they consider it impossible to introduce randomization address space at a smaller granularity than code segment.
In addition, address space randomization also makes the use of software integrity verification more difficult since the code moves in the memory space.
To counter tampering attacks, such integrity verification techniques are used to ensure that the code has not been modified.
Prior art methods of verifying the integrity of a program compute a signature (a.k.a. checksum) over at least some parts of the code. A signature may for example be a hash value, calculated over the parts of the code, and then signed using a secret key. The skilled person will appreciate that numerous other possibilities exist. During program execution, the signature of the code is calculated at least once. To increase the security level, the functions that calculate the signatures are nested, so that the integrity of each function is verified by at least one other function. Thus, if just one function remains intact, it will detect tampering with at least one other function. Further details and explanations may for example be found in US 2003/188231 and EP 1942431, and US 2002/138748 teaches how to determine integrity for relocatable code.
Unfortunately, integrity verification techniques are vulnerable to reverse engineering, such as the use of hardware breakpoints.
As also software integrity verification is a useful tool against reverse engineering, it will be appreciated that there are situations where it is desired to ensure the integrity of a software program that uses address space randomization.
It is thus a problem to check the integrity of dynamically relocated code.
A trivial solution is to pass the range of the relocated code as an input parameter to a checksum function. From a security point of view, this is not acceptable since it reveals the range of the protected function and the reference value to an attacker.
It will thus be appreciated that there is a need for a solution that enables the computation of a checksum on a relocated function, without revealing such details about the function. The present application provides such a solution.